home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / library / kern_descrip.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  9KB  |  379 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  kern_descrip.c,v 1.1.1.1 1994/04/04 04:30:42 amiga Exp
  20.  *
  21.  *  kern_descrip.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:42  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.2  1992/07/04  19:19:04  mwild
  26.  *  add support for F_INTERNALIZE/F_EXTERNALIZE, which are used by IXPIPE
  27.  *  and execve().
  28.  *
  29.  * Revision 1.1  1992/05/14  19:55:40  mwild
  30.  * Initial revision
  31.  *
  32.  *
  33.  *  Since the code originated from Berkeley, the following copyright
  34.  *  header applies as well. The code has been changed, it's not the
  35.  *  original Berkeley code!
  36.  */
  37.  
  38. /*
  39.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  40.  * All rights reserved.
  41.  *
  42.  * Redistribution is only permitted until one year after the first shipment
  43.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  44.  * binary forms are permitted provided that: (1) source distributions retain
  45.  * this entire copyright notice and comment, and (2) distributions including
  46.  * binaries display the following acknowledgement:  This product includes
  47.  * software developed by the University of California, Berkeley and its
  48.  * contributors'' in the documentation or other materials provided with the
  49.  * distribution and in all advertising materials mentioning features or use
  50.  * of this software.  Neither the name of the University nor the names of
  51.  * its contributors may be used to endorse or promote products derived from
  52.  * this software without specific prior written permission.
  53.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  54.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  55.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  56.  *
  57.  *    @(#)kern_descrip.c    7.16 (Berkeley) 6/28/90
  58.  */
  59.  
  60. #define KERNEL
  61. #include "ixemul.h"
  62. #include "kprintf.h"
  63.  
  64. extern int __sync_write (), __write ();
  65.  
  66. /*
  67.  * Descriptor management.
  68.  */
  69.  
  70. /*
  71.  * System calls on descriptors.
  72.  */
  73. /* ARGSUSED */
  74. int
  75. getdtablesize ()
  76. {
  77.   errno = 0;
  78.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  79.   return NOFILE;
  80. }
  81.  
  82. /*
  83.  * Duplicate a file descriptor.
  84.  */
  85. /* ARGSUSED */
  86. int
  87. dup (unsigned i)
  88. {
  89.   struct file *fp;
  90.   int fd, error;
  91.  
  92.   if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
  93.     {
  94.       errno = EBADF;
  95.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  96.       return -1;
  97.     }
  98.  
  99.   if (error = ufalloc (0, &fd))
  100.     {
  101.       errno = error;
  102.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  103.       return -1;
  104.     }
  105.  
  106.   u.u_ofile[fd] = fp;
  107.   u.u_pofile[fd] = u.u_pofile[i] &~ UF_EXCLOSE;
  108.   fp->f_count++;
  109.  
  110.   if (fd > u.u_lastfile) u.u_lastfile = fd;
  111.  
  112.   errno = 0;
  113.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  114.   return fd;
  115. }
  116.  
  117. /*
  118.  * Duplicate a file descriptor to a particular value.
  119.  */
  120. /* ARGSUSED */
  121. int
  122. dup2 (unsigned i, unsigned j)
  123. {
  124.   register struct file *fp;
  125.   int error;
  126.  
  127.   if (i >= NOFILE || (fp = u.u_ofile[i]) == NULL)
  128.     {
  129.       errno = EBADF;
  130.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  131.       return -1;
  132.     }
  133.  
  134.   if (j < 0 || j >= NOFILE)
  135.     {
  136.       errno = EBADF;
  137.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  138.       return -1;
  139.     }
  140.  
  141.   errno = 0;
  142.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  143.   if (i == j) return (int)j;
  144.  
  145.   ix_lock_base ();
  146.  
  147.   if (u.u_ofile[j] && u.u_ofile[j]->f_close)
  148.     u.u_ofile[j]->f_close (u.u_ofile[j]);
  149.  
  150.   u.u_ofile[j] = fp;
  151.   u.u_pofile[j] = u.u_pofile[i] &~ UF_EXCLOSE;
  152.   fp->f_count++;
  153.   if (j > u.u_lastfile)
  154.     u.u_lastfile = j;
  155.   
  156.   ix_unlock_base ();
  157.  
  158.   /*
  159.    * dup2() must suceed even though the close had an error.
  160.    */
  161.   errno = 0;        /* XXX */
  162.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  163.   return (int)j;
  164. }
  165.  
  166. /*
  167.  * The file control system call.
  168.  */
  169. /* ARGSUSED */
  170. int
  171. fcntl(unsigned fdes, int cmd, int arg)
  172. {
  173.   register struct file *fp;
  174.   register char *pop;
  175.   int i, error;
  176.  
  177.   /* F_INTERNALIZE doesn't need a valid descriptor. Check for this first */
  178.   if (cmd == F_INTERNALIZE)
  179.     {
  180.       if (error = ufalloc (0, &i))
  181.         {
  182.           errno = error;
  183.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  184.           return -1;
  185.         }
  186.       fp = (struct file *) arg;
  187.       u.u_ofile[i] = fp;
  188.       u.u_pofile[i] = 0;
  189.       fp->f_count++;
  190.       return i;
  191.     }
  192.  
  193.  
  194.   if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
  195.     {
  196.       errno = EBADF;
  197.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  198.       return -1;
  199.     }
  200.  
  201.   pop = &u.u_pofile[fdes];
  202.   switch (cmd) 
  203.     {
  204.       case F_DUPFD:
  205.     if (arg < 0 || arg >= NOFILE)
  206.       {
  207.         errno = EINVAL; 
  208.         KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  209.         return -1;
  210.       }
  211.     if (error = ufalloc (arg, &i))
  212.       {
  213.         errno = error;
  214.         KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  215.         return -1;
  216.       }
  217.     ix_lock_base ();
  218.     u.u_ofile[i] = fp;
  219.     u.u_pofile[i] = *pop &~ UF_EXCLOSE;
  220.     fp->f_count++;
  221.     ix_unlock_base ();
  222.     if (i > u.u_lastfile) u.u_lastfile = i;
  223.     errno = 0;
  224.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  225.     return (int)i;
  226.  
  227.       case F_GETFD:
  228.         errno = 0;
  229.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  230.     return *pop & 1;
  231.  
  232.       case F_SETFD:
  233.     *pop = (*pop &~ 1) | (arg & 1);
  234.     errno = 0;
  235.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  236.     return 0;
  237.  
  238.       case F_GETFL:
  239.         errno = 0;
  240.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  241.     return OFLAGS(fp->f_flags);
  242.  
  243.       case F_SETFL:
  244.     arg &= FCNTLFLAGS;
  245.         if (fp->f_type == DTYPE_FILE)
  246.       {
  247.             fp->f_flags = arg;
  248.             if (fp->f_write) fp->f_write = (arg & O_FSYNC)  ? __sync_write :__write;
  249.       }
  250.     errno = 0;
  251.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  252.     return 0;
  253.  
  254.       case F_EXTERNALIZE:
  255.         return (int)fp;
  256.  
  257.       default:
  258.         errno = EINVAL;
  259.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  260.     return -1;
  261.     }
  262.     /* NOTREACHED */
  263. }
  264.  
  265. /*
  266.  * Return status information about a file descriptor.
  267.  */
  268. /* ARGSUSED */
  269. int
  270. fstat (unsigned fdes, struct stat *sb)
  271. {
  272.   register struct file *fp;
  273.  
  274.   if (fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL)
  275.     {
  276.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  277.       errno = EBADF;
  278.       return -1;
  279.     }
  280.  
  281.   /* if this file is writable, then it's quite probably that the stat buffer
  282.      information stored at open time is no longer valid. So if the file really
  283.      is a file, update that information */
  284.   if ((fp->f_flags & FWRITE) && fp->f_type == DTYPE_FILE)
  285.     __fstat (fp);
  286.  
  287.   *sb = fp->f_stb;
  288.   return 0;
  289. }
  290.  
  291. /*
  292.  * Allocate a user file descriptor.
  293.  */
  294. int
  295. ufalloc(int want, int *result)
  296. {
  297.   for (; want < NOFILE; want++) 
  298.     {
  299.       if (u.u_ofile[want] == NULL) 
  300.         {
  301.       u.u_pofile[want] = 0;
  302.       if (want > u.u_lastfile) u.u_lastfile = want;
  303.             
  304.       *result = want;
  305.       return 0;
  306.     }
  307.     }
  308.   return EMFILE;
  309. }
  310.  
  311. /*
  312.  * Allocate a user file descriptor
  313.  * and a file structure.
  314.  * Initialize the descriptor
  315.  * to point at the file structure.
  316.  */
  317. int
  318. falloc(struct file **resultfp, int *resultfd)
  319. {
  320.   register struct file *fp;
  321.   int error, i;
  322.  
  323.   if (error = ufalloc(0, &i))
  324.     return (error);
  325.  
  326.   ix_lock_base ();
  327.  
  328.   if (ix.ix_lastf == 0)
  329.     ix.ix_lastf = ix.ix_file_tab;
  330.  
  331.   for (fp = ix.ix_lastf; fp < ix.ix_fileNFILE; fp++)
  332.     if (fp->f_count == 0)
  333.       goto slot;
  334.  
  335.   for (fp = ix.ix_file_tab; fp < ix.ix_lastf; fp++)
  336.     if (fp->f_count == 0)
  337.       goto slot;
  338.  
  339.   /* YES I know.. it's not optimal, we should resize the table...
  340.    * unfortunately all code accessing file structures will then have
  341.    * to be changed as well, and this is a job for later improvement,
  342.    * first goal is to get this baby working... */
  343.   ix_panic ("ixemul.library file table full!");
  344.   error = ENFILE;
  345.   goto do_ret;
  346.  
  347. slot:
  348.   u.u_ofile[i] = fp;
  349.   fp->f_name = 0;
  350.   fp->f_count = 1;
  351.   fp->f_type = 0;        /* inexistant type ;-) */
  352.   fp->f_async_buf = 0;
  353.   fp->f_async_len = 0;
  354.   ix.ix_lastf = fp + 1;
  355.   if (resultfp)
  356.     *resultfp = fp;
  357.   if (resultfd)
  358.     *resultfd = i;
  359.  
  360.   error = 0;
  361.  
  362. do_ret:
  363.   ix_unlock_base();
  364.  
  365.   return error;
  366. }
  367.  
  368.  
  369. /*
  370.  * Apply an advisory lock on a file descriptor.
  371.  */
  372. /* ARGSUSED */
  373. int
  374. flock (int fdes, int how)
  375. {
  376.   return 0;    /* always succeed */
  377. }
  378.  
  379.